using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using S.M.SmartMedical.API.Write.Application.Command;
using S.M.SmartMedical.Domain.DTOs;
using S.M.SmartMedical.Domain.Entities;
using S.M.SmartMedical.ErrorCode;
using S.M.SmartMedical.Infrastructure.BaseRepository;
using System.Text.Json;

namespace S.M.SmartMedical.API.Write.Application.Handler
{
    /// <summary>
    /// 创建医院院区命令处理器
    /// 处理新增医院院区的业务逻辑
    /// </summary>
    public class CreateHospitalAreaHandler : IRequestHandler<CreateHospitalAreaCommand, APIResult<HospitalAreaDto>>
    {
        private readonly IRepository<HospitalArea> _hospitalAreaRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<CreateHospitalAreaHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="hospitalAreaRepository">院区仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public CreateHospitalAreaHandler(
            IRepository<HospitalArea> hospitalAreaRepository,
            IMapper mapper,
            ILogger<CreateHospitalAreaHandler> logger)
        {
            _hospitalAreaRepository = hospitalAreaRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理创建医院院区命令
        /// </summary>
        /// <param name="request">创建命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>创建结果</returns>
        public async Task<APIResult<HospitalAreaDto>> Handle(CreateHospitalAreaCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始创建医院院区，院区名称：{Name}", request.Name);

                // 检查院区名称是否已存在
                var existingArea = await _hospitalAreaRepository.GetAllAsync()
                    .FirstOrDefaultAsync(x => x.Name == request.Name && !x.IsDeleted, cancellationToken);

                if (existingArea != null)
                {
                    _logger.LogWarning("创建医院院区失败，院区名称已存在：{Name}", request.Name);
                    return new APIResult<HospitalAreaDto>
                    {
                        Code = APIEnum.Fail,
                        Message = "院区名称已存在",
                        Data = null
                    };
                }

                // 创建新的院区实体
                var hospitalArea = new HospitalArea
                {
                    Name = request.Name,
                    Address = request.Address,
                    Phone = request.Phone,
                    Description = request.Description,
                    IsSelfServiceEnabled = request.IsSelfServiceEnabled,
                    Tags = request.Tags.Any() ? JsonSerializer.Serialize(request.Tags) : null,
                    Longitude = request.Longitude,
                    Latitude = request.Latitude,
                    SortOrder = request.SortOrder,
                    IsEnabled = true,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now
                };

                // 保存到数据库
                var result = await _hospitalAreaRepository.AddAsync(hospitalArea);

                if (result <= 0)
                {
                    _logger.LogError("创建医院院区失败，数据保存失败，院区名称：{Name}", request.Name);
                    return new APIResult<HospitalAreaDto>
                    {
                        Code = APIEnum.Fail,
                        Message = "创建医院院区失败",
                        Data = null
                    };
                }

                _logger.LogInformation("成功创建医院院区，院区ID：{Id}，院区名称：{Name}", hospitalArea.Id, hospitalArea.Name);

                // 映射到DTO并返回
                var dto = _mapper.Map<HospitalAreaDto>(hospitalArea);
                
                // 解析标签JSON字符串
                if (!string.IsNullOrWhiteSpace(hospitalArea.Tags))
                {
                    try
                    {
                        dto.Tags = JsonSerializer.Deserialize<List<string>>(hospitalArea.Tags) ?? new List<string>();
                    }
                    catch (JsonException ex)
                    {
                        _logger.LogWarning("解析院区标签JSON失败，院区ID：{AreaId}，错误：{Error}", hospitalArea.Id, ex.Message);
                        dto.Tags = new List<string>();
                    }
                }

                return new APIResult<HospitalAreaDto>
                {
                    Code = APIEnum.OK,
                    Message = "创建医院院区成功",
                    Data = dto
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建医院院区时发生异常，院区名称：{Name}", request.Name);
                return new APIResult<HospitalAreaDto>
                {
                    Code = APIEnum.Fail,
                    Message = "创建医院院区失败，请稍后重试",
                    Data = null
                };
            }
        }
    }
}